﻿using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using UIOC.CodeAnalysis.Diagnostics;
using UIOC.CodeAnalysis.Extensions;
using UIOC.CodeAnalysis.Helpers;

namespace UIOC.CodeAnalysis.Generators;

internal static class BeanMembersGenerator {

    public readonly struct GeneratedInfo(GeneratedSource source, ImmutableArray<Diagnostic> diagnostics) {

        public GeneratedSource GeneratedSource { get; } = source;

        public ImmutableArray<Diagnostic> Diagnostics { get; } = diagnostics;
    }

    private sealed class CS0695Exception : NotSupportedException {
        public List<(
            INamedTypeSymbol ClassTypeSymbol,
            INamedTypeSymbol InterfaceTypeSymbol1,
            INamedTypeSymbol InterfaceTypeSymbol2
        )> List;
    }

    private static void LogInfo(string message) {
        SourceOutputHelper.LogInfo(DiagnosticSeverity.Info, $"[{nameof(BeanMembersGenerator)}] {message}");
    }

    public static ImmutableArray<GeneratedInfo> GenerateBeanMembers(
        Compilation compilation,
        ImmutableDictionary<INamedTypeSymbol, BeanGenerator.GeneratedInfo> beanGeneratedSourceDictionary
    ) {
        var implementAttributeSymbol = compilation.GetTypeByMetadataName(AttributeFullNames.Implement);
        if (implementAttributeSymbol == null) {
            return ImmutableArray<GeneratedInfo>.Empty;
        }

        var beanRegisterAttributeSymbol = compilation.GetTypeByMetadataName(AttributeFullNames.BeanRegister);
        if (beanRegisterAttributeSymbol == null) {
            return ImmutableArray<GeneratedInfo>.Empty;
        }

        var objectInterfaceSymbol = compilation.GetTypeByMetadataName(TypeFullNames.IObject);
        if (objectInterfaceSymbol == null) {
            return ImmutableArray<GeneratedInfo>.Empty;
        }

        var objectInternalInterfaceSymbol = compilation.GetTypeByMetadataName(TypeFullNames.IObjectInternal);
        if (objectInternalInterfaceSymbol == null) {
            return ImmutableArray<GeneratedInfo>.Empty;
        }

        var pooledObjectInternalInterfaceSymbol = compilation.GetTypeByMetadataName(TypeFullNames.IPooledObjectInternal);
        if (pooledObjectInternalInterfaceSymbol == null) {
            return ImmutableArray<GeneratedInfo>.Empty;
        }

        var beanObjectInternalInterfaceSymbol = compilation.GetTypeByMetadataName(TypeFullNames.IBeanObjectInternal);
        if (beanObjectInternalInterfaceSymbol == null) {
            return ImmutableArray<GeneratedInfo>.Empty;
        }

        var beanInternalInterfaceSymbol = compilation.GetTypeByMetadataName(TypeFullNames.IBeanInternal);
        if (beanInternalInterfaceSymbol == null) {
            return default;
        }

        var beanInterfaceSymbol = compilation.GetTypeByMetadataName(TypeFullNames.IBean);
        if (beanInterfaceSymbol == null) {
            return default;
        }

        var ignoreNamedTypeSymbolSet = new HashSet<INamedTypeSymbol>(SymbolEqualityComparer.Default) {
            objectInterfaceSymbol,
            objectInternalInterfaceSymbol,
            pooledObjectInternalInterfaceSymbol,
            beanObjectInternalInterfaceSymbol,
            beanInternalInterfaceSymbol,
            beanInterfaceSymbol,
        };

        LogInfo($"[Assembly({compilation.Assembly.Name})] {nameof(GenerateBeanMembers)} ...");

        var result = ImmutableArray.CreateBuilder<GeneratedInfo>();

        var objectSymbols = beanGeneratedSourceDictionary.Keys;

        foreach (var objectSymbol in objectSymbols) {
            try {
                var (compilationUnitSyntax, namespaceName) = GenerateBeanCompilationUnit(
                   ignoreNamedTypeSymbolSet,
                   compilation,
                   objectSymbol
               );
                if (compilationUnitSyntax == null) {
                    continue;
                }
                var outputSource = SourceText.From(compilationUnitSyntax.NormalizeWhitespace().ToFullString(), Encoding.UTF8);
                var hintName = objectSymbol.GetShortName().Replace("<", "(").Replace(">", ")");
                result.Add(new GeneratedInfo(
                    new GeneratedSource(
                        hintName: hintName,
                        assemblyName: compilation.Assembly.Name,
                        namespaceName: namespaceName,
                        sourceText: outputSource,
                        compilationUnitSyntax: compilationUnitSyntax,
                        generatorName: nameof(BeanMembersGenerator)
                    ),
                    ImmutableArray<Diagnostic>.Empty
                ));
            } catch (CS0695Exception e) {
                Location location;
                if (e.List[0].ClassTypeSymbol.GetUserSyntaxReferences().FirstOrDefault()?.GetSyntax() is not ClassDeclarationSyntax userClassDeclarationSyntax) {
                    var objectClassDeclarationSyntax = objectSymbol.GetUserSyntaxReferences().First().GetSyntax();
                    var implementAttributeData = objectSymbol.GetAttributes(implementAttributeSymbol).FirstOrDefault();
                    if (implementAttributeData == null) {
                        location = objectClassDeclarationSyntax.GetLocation();
                    } else if (implementAttributeData.ConstructorArguments.Length > 0
                        && implementAttributeData.ConstructorArguments[0].Value is INamedTypeSymbol typeSymbol
                        && typeSymbol.TypeKind == TypeKind.Interface
                    ) {
                        location = (typeSymbol.GetUserSyntaxReferences().FirstOrDefault()?.GetSyntax() as InterfaceDeclarationSyntax).Identifier.GetLocation();
                    } else {
                        location = objectClassDeclarationSyntax.GetLocation();
                    }
                } else {
                    location = userClassDeclarationSyntax.Identifier.GetLocation();
                }
                var diagnostics = ImmutableArray.CreateBuilder<Diagnostic>();
                foreach (var (ClassTypeSymbol, InterfaceTypeSymbol1, InterfaceTypeSymbol2) in e.List) {
                    diagnostics.Add(Diagnostic.Create(
                        CS0695_CompilerDiagnostic.Rule,
                        location,
                        ClassTypeSymbol.ToString(),
                        InterfaceTypeSymbol1.ToString(),
                        InterfaceTypeSymbol2.ToString()
                    ));
                }
                result.Add(new GeneratedInfo(null, diagnostics.ToImmutable()));
            }
        }
        return result.ToImmutable();
    }

    private static (CompilationUnitSyntax CompilationUnitSyntax, string NamespaceName) GenerateBeanCompilationUnit(
        HashSet<INamedTypeSymbol> IgnoreNamedTypeSymbolSet,
        Compilation compilation,
        INamedTypeSymbol objectSymbol
    ) {
        var className = $"{objectSymbol.Name}{BeanGenerator.BEAN_TYPE_SUFFIX}";

        var allInterfaceTypeSymbolSet = GetAllInterfaces(
            objectSymbol,
            IgnoreNamedTypeSymbolSet
        ).ToImmutableHashSet<INamedTypeSymbol>(SymbolEqualityComparer.Default);

        var allGenericTypeDefinitionSymbolSet = allInterfaceTypeSymbolSet.Select(symbol => {
            if (symbol.IsGenericType && symbol.TypeArguments.Any(arg => arg is ITypeParameterSymbol)) {
                return symbol.ConstructedFrom;
            }
            return null;
        }).Where(item => item != null).ToImmutableHashSet(SymbolEqualityComparer.Default);

        var errorList = new List<(INamedTypeSymbol, INamedTypeSymbol, INamedTypeSymbol)>();
        foreach (var symbol in allInterfaceTypeSymbolSet) {
            if (symbol.IsGenericType
                && !symbol.IsDefinition
                && !symbol.TypeArguments.Any(arg => arg is ITypeParameterSymbol)
                && allGenericTypeDefinitionSymbolSet.Contains(symbol.ConstructedFrom.ConstructedFrom)
            ) {
                errorList.Add((objectSymbol, symbol.ConstructedFrom, symbol));
            }
        }
        if (errorList.Any()) {
            throw new CS0695Exception { List = errorList };
        }

        var memberDeclarationSyntaxes = allInterfaceTypeSymbolSet.SelectMany(
            GenerateMembers
        );

        var classDeclarationSyntax = SyntaxFactory.ClassDeclaration(className)
            .AddModifiers(
                SyntaxFactory.Token(SyntaxKind.PrivateKeyword),
                SyntaxFactory.Token(SyntaxKind.SealedKeyword),
                SyntaxFactory.Token(SyntaxKind.PartialKeyword)
            )
            .AddMembers([.. memberDeclarationSyntaxes]);

        if (allInterfaceTypeSymbolSet.Any()) {
            classDeclarationSyntax = classDeclarationSyntax.AddBaseListTypes([
                .. allInterfaceTypeSymbolSet.Select(@interface => @interface.CreateSimpleBaseTypeSyntax())
            ]);
        }

        if (objectSymbol.TypeParameters.Length > 0) {
            classDeclarationSyntax = classDeclarationSyntax.AddTypeParameterListParameters([.. objectSymbol.TypeParameters.Select(tp => SyntaxFactory.TypeParameter(tp.Name))]);
            classDeclarationSyntax = classDeclarationSyntax.AddConstraintClauses([.. objectSymbol.GetConstraintClauses()]);
        }

        var registrationClassDeclarationSyntax = SyntaxFactory.ClassDeclaration(TypeRegistrationGenerator.CLASS_NAME_TYPE_REGISTRATIONS)
            .AddModifiers(
                SyntaxFactory.Token(SyntaxKind.InternalKeyword),
                SyntaxFactory.Token(SyntaxKind.StaticKeyword),
                SyntaxFactory.Token(SyntaxKind.PartialKeyword)
            )
            .AddMembers(classDeclarationSyntax);

        var leadingTriviaSyntax = SyntaxFactory.Comment(UIOCGenerator.Leading);
        var namespaceName = compilation.Assembly.Name;
        var namespaceDeclarationSyntax = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(namespaceName))
            .WithLeadingTrivia(leadingTriviaSyntax)
            .AddMembers(registrationClassDeclarationSyntax);

        var compilationUnit = SyntaxFactory.CompilationUnit()
            .AddMembers(namespaceDeclarationSyntax);

        return (compilationUnit, $"{namespaceName}__{TypeRegistrationGenerator.CLASS_NAME_TYPE_REGISTRATIONS}");
    }

    private static IEnumerable<INamedTypeSymbol> GetAllInterfaces(
        INamedTypeSymbol objectNamedTypeSymbol,
        HashSet<INamedTypeSymbol> ignoreSet
    ) {
        if (objectNamedTypeSymbol == null || ignoreSet.Contains(objectNamedTypeSymbol)) {
            yield break;
        }
        foreach (var interfaceNamedTypeSymbol in objectNamedTypeSymbol.Interfaces) {
            if (ignoreSet.Contains(interfaceNamedTypeSymbol)) {
                continue;
            }
            yield return interfaceNamedTypeSymbol;
            foreach (var @interface in GetAllInterfaces(interfaceNamedTypeSymbol, ignoreSet)) {
                yield return @interface;
            }
        }
        if (objectNamedTypeSymbol.TypeKind != TypeKind.Interface) {
            foreach (var baseInterface in GetAllInterfaces(objectNamedTypeSymbol.BaseType, ignoreSet)) {
                yield return baseInterface;
            }
        }
    }

    /// <summary>
    /// 基于m_Object显式实现接口的所有成员，使用(m_Object as 接口)进行调用
    /// </summary>
    /// <param name="interfaceSymbol">目标接口符号</param>
    /// <returns>接口所有成员的显式实现语法节点列表</returns>
    private static IEnumerable<MemberDeclarationSyntax> GenerateMembers(INamedTypeSymbol interfaceSymbol) {
        if (interfaceSymbol == null || interfaceSymbol.TypeKind != TypeKind.Interface)
            yield break;

        foreach (var member in interfaceSymbol.GetMembers()) {
            switch (member.Kind) {
                case SymbolKind.Method:
                    if (member is IMethodSymbol methodSymbol && methodSymbol.MethodKind == MethodKind.Ordinary) {
                        var methodDeclarationSyntax = GenerateMethodDeclaration(interfaceSymbol, methodSymbol);
                        if (methodDeclarationSyntax != null) {
                            yield return methodDeclarationSyntax;
                        }
                    }
                    break;
                case SymbolKind.Property:
                    if (member is IPropertySymbol propertySymbol) {
                        var propertyDeclarationSyntax = GeneratePropertyDeclaration(interfaceSymbol, propertySymbol);
                        if (propertyDeclarationSyntax != null) {
                            yield return propertyDeclarationSyntax;
                        }
                    }
                    break;
                case SymbolKind.Event:
                    if (member is IEventSymbol eventSymbol) {
                        var eventDeclarationSyntax = GenerateEventDeclaration(interfaceSymbol, eventSymbol);
                        if (eventDeclarationSyntax != null) {
                            yield return eventDeclarationSyntax;
                        }
                    }
                    break;
            }
        }
    }

    /// <summary>
    /// 生成方法的显式实现：使用(m_Object as 接口).方法(参数)
    /// </summary>
    public static MethodDeclarationSyntax GenerateMethodDeclaration(INamedTypeSymbol interfaceSymbol, IMethodSymbol methodSymbol) {
        var interfaceNameSyntax = interfaceSymbol.CreateSimpleNameSyntax();
        var explicitInterfaceSpecifierSyntax = SyntaxFactory.ExplicitInterfaceSpecifier(
            interfaceNameSyntax
        );

        var expressionSyntax = SyntaxFactory.ParenthesizedExpression(SyntaxFactory.BinaryExpression(
            SyntaxKind.AsExpression,
            SyntaxFactory.IdentifierName(BeanGenerator.OBJECT_FIELD_NAME),
            interfaceNameSyntax
        ));

        // 处理泛型方法
        SimpleNameSyntax methodNameSyntax = SyntaxFactory.IdentifierName(methodSymbol.Name);
        if (methodSymbol.IsGenericMethod) {
            methodNameSyntax = SyntaxFactory.GenericName(
                methodNameSyntax.Identifier
            ).AddTypeArgumentListArguments([.. methodSymbol.TypeParameters.Select(tp => SyntaxFactory.IdentifierName(tp.Name))]);
        }

        // 构建 (m_Object as IInterface).Method(...) 调用
        var invocationExpressionSyntax = SyntaxFactory.InvocationExpression(
            SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                expressionSyntax,
                methodNameSyntax
            )
        ).AddArgumentListArguments([
            .. methodSymbol.Parameters.Select(
                param => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(param.Name))
                    .WithRefKindKeyword(param.RefKind.ToKeyword().FirstOrDefault())
            )
        ]);

        // 构建方法体
        StatementSyntax bodyStatementSyntax;
        if (methodSymbol.ReturnType.SpecialType == SpecialType.System_Void) {
            bodyStatementSyntax = SyntaxFactory.ExpressionStatement(invocationExpressionSyntax)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));
        } else {
            bodyStatementSyntax = SyntaxFactory.ReturnStatement(invocationExpressionSyntax)
                .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken));
        }

        var ifDirectiveSyntax = SyntaxFactory.IfDirectiveTrivia(
            SyntaxFactory.IdentifierName("!DISABLE_DEBUGGER_ATTRIBUTE"),
            isActive: true,
            branchTaken: true,
            conditionValue: true
        );
        var endIfDirectiveSyntax = SyntaxFactory.EndIfDirectiveTrivia(isActive: true);

        var methodBodySyntax = SyntaxFactory.Block(
            BeanGenerator.GenerateAssertDisposeExpressionStatement(),
            bodyStatementSyntax
        );

        // 构建完整方法声明
        var methodDeclaration = SyntaxFactory.MethodDeclaration(
            methodSymbol.ReturnsVoid
                ? SyntaxFactory.IdentifierName("void")
                : (methodSymbol.ReturnType is INamedTypeSymbol returnNamedTypeSymbol
                    ? returnNamedTypeSymbol.CreateSimpleNameSyntax(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList<TypeSyntax>(
                        returnNamedTypeSymbol.TypeArguments.Select(
                            arg => arg is INamedTypeSymbol argNamedTypeSymbol
                                ? argNamedTypeSymbol.CreateSimpleNameSyntax()
                                : GetTypeArgumentTypeName(interfaceSymbol, arg.Name)
                        )
                    )))
                    : GetTypeArgumentTypeName(interfaceSymbol, methodSymbol.ReturnType.Name)
                ),
            methodSymbol.Name
        )
            .WithExplicitInterfaceSpecifier(explicitInterfaceSpecifierSyntax)
            .AddParameterListParameters([.. methodSymbol.Parameters.Select(param =>
                SyntaxFactory.Parameter(
                    attributeLists: default,
                    modifiers: param.RefKind.ToKeyword(),
                    type: GetParameterType(param.Type, interfaceSymbol),
                    identifier: SyntaxFactory.Identifier(param.Name),
                    @default: null
                )
            )])
            .WithBody(methodBodySyntax)
            .AddAttributeLists([
                SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList([
                    SyntaxFactory.Attribute(SyntaxFactory.QualifiedName(
                        SyntaxFactory.IdentifierName($"global::{nameof(System)}.{nameof(System.Diagnostics)}"),
                        SyntaxFactory.IdentifierName(nameof(System.Diagnostics.DebuggerHiddenAttribute))
                    )),
                ])).WithLeadingTrivia(
                    SyntaxFactory.Trivia(ifDirectiveSyntax),
                    SyntaxFactory.CarriageReturnLineFeed
                ).WithTrailingTrivia(
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Trivia(endIfDirectiveSyntax)
                )
            ]);

        // 添加泛型参数
        if (methodSymbol.IsGenericMethod) {
            methodDeclaration = methodDeclaration.AddTypeParameterListParameters([
                .. methodSymbol.TypeParameters.Select(tp => SyntaxFactory.TypeParameter(tp.Name))
            ]);
        }

        return methodDeclaration;
    }

    /// <summary>
    /// 生成属性的显式实现：使用(m_Object as 接口).属性
    /// </summary>
    private static BasePropertyDeclarationSyntax GeneratePropertyDeclaration(INamedTypeSymbol interfaceSymbol, IPropertySymbol propertySymbol) {
        var interfaceNameSyntax = interfaceSymbol.CreateSimpleNameSyntax();
        var explicitInterfaceSpecifierSyntax = SyntaxFactory.ExplicitInterfaceSpecifier(
            interfaceNameSyntax
        );

        var expressionSyntax = SyntaxFactory.ParenthesizedExpression(SyntaxFactory.BinaryExpression(
            SyntaxKind.AsExpression,
            SyntaxFactory.IdentifierName(BeanGenerator.OBJECT_FIELD_NAME),
            interfaceNameSyntax
        ));

        ExpressionSyntax memberAccess = propertySymbol.IsIndexer
            ? SyntaxFactory.ElementAccessExpression(
                expressionSyntax,
                SyntaxFactory.BracketedArgumentList(
                    SyntaxFactory.SeparatedList(propertySymbol.Parameters.Select(param =>
                        SyntaxFactory.Argument(SyntaxFactory.IdentifierName(param.Name))
                    ))
                )
            )
            : SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                expressionSyntax,
                SyntaxFactory.IdentifierName(propertySymbol.Name)
            );

        var getAccessor = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
           .WithBody(SyntaxFactory.Block(
               BeanGenerator.GenerateAssertDisposeExpressionStatement(),
               SyntaxFactory.ReturnStatement(memberAccess)
           ))
           .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None));

        var setAccessor = SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
            .WithBody(SyntaxFactory.Block(
                BeanGenerator.GenerateAssertDisposeExpressionStatement(),
                SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.AssignmentExpression(
                        SyntaxKind.SimpleAssignmentExpression,
                        memberAccess,
                        SyntaxFactory.IdentifierName("value")
                    )
                )
            ))
            .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None));

        var ifDirectiveSyntax = SyntaxFactory.IfDirectiveTrivia(
            SyntaxFactory.IdentifierName("!DISABLE_DEBUGGER_ATTRIBUTE"),
            isActive: true,
            branchTaken: true,
            conditionValue: true
        );
        var endIfDirectiveSyntax = SyntaxFactory.EndIfDirectiveTrivia(isActive: true);

        BasePropertyDeclarationSyntax propertyDeclaration = propertySymbol.IsIndexer
            ? SyntaxFactory.IndexerDeclaration(
                (propertySymbol.Type is INamedTypeSymbol)
                    ? propertySymbol.Type.CreateSimpleNameSyntax(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList<TypeSyntax>(
                        (propertySymbol.Type as INamedTypeSymbol).TypeArguments.Select(
                            arg => arg is INamedTypeSymbol argNamedTypeSymbol
                                ? argNamedTypeSymbol.CreateSimpleNameSyntax()
                                : GetTypeArgumentTypeName(interfaceSymbol, arg.Name)
                        )
                    )))
                    : SyntaxFactory.IdentifierName(propertySymbol.Type.Name)
            ).WithParameterList(SyntaxFactory.BracketedParameterList(SyntaxFactory.SeparatedList<ParameterSyntax>(propertySymbol.Parameters.Select(
                parameter => SyntaxFactory.Parameter(SyntaxFactory.Identifier(parameter.Name))
                    .WithType(parameter.Type is INamedTypeSymbol parameterNamedTypeSymbol
                        ? parameterNamedTypeSymbol.CreateSimpleNameSyntax()
                        : GetTypeArgumentTypeName(interfaceSymbol, parameter.Type.Name)
                    )
            )))).WithExplicitInterfaceSpecifier(explicitInterfaceSpecifierSyntax)
            : SyntaxFactory.PropertyDeclaration(
                (propertySymbol.Type is INamedTypeSymbol)
                    ? propertySymbol.Type.CreateSimpleNameSyntax(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList<TypeSyntax>(
                        (propertySymbol.Type as INamedTypeSymbol).TypeArguments.Select(
                            arg => arg is INamedTypeSymbol argNamedTypeSymbol
                                ? argNamedTypeSymbol.CreateSimpleNameSyntax()
                                : GetTypeArgumentTypeName(interfaceSymbol, arg.Name)
                        )
                    )))
                    : SyntaxFactory.IdentifierName(propertySymbol.Type.Name),
                propertySymbol.Name
            ).WithExplicitInterfaceSpecifier(explicitInterfaceSpecifierSyntax)
            .AddAttributeLists([
                SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList([
                    SyntaxFactory.Attribute(SyntaxFactory.QualifiedName(
                        SyntaxFactory.IdentifierName($"global::{nameof(System)}.{nameof(System.Diagnostics)}"),
                        SyntaxFactory.IdentifierName(nameof(System.Diagnostics.DebuggerHiddenAttribute))
                    )),
                ])).WithLeadingTrivia(
                    SyntaxFactory.Trivia(ifDirectiveSyntax),
                    SyntaxFactory.CarriageReturnLineFeed
                ).WithTrailingTrivia(
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Trivia(endIfDirectiveSyntax)
                )
            ]);

        if (propertySymbol.GetMethod != null) {
            propertyDeclaration = propertyDeclaration.AddAccessorListAccessors(getAccessor);
        }

        if (propertySymbol.SetMethod != null) {
            propertyDeclaration = propertyDeclaration.AddAccessorListAccessors(setAccessor);
        }

        return propertyDeclaration;
    }

    /// <summary>
    /// 生成事件的显式实现：使用(m_Object as 接口).事件
    /// </summary>
    private static EventDeclarationSyntax GenerateEventDeclaration(INamedTypeSymbol interfaceSymbol, IEventSymbol eventSymbol) {
        var interfaceNameSyntax = interfaceSymbol.CreateSimpleNameSyntax();
        var explicitInterfaceSpecifierSyntax = SyntaxFactory.ExplicitInterfaceSpecifier(
            interfaceNameSyntax
        );

        var expressionSyntax = SyntaxFactory.ParenthesizedExpression(SyntaxFactory.BinaryExpression(
            SyntaxKind.AsExpression,
            SyntaxFactory.IdentifierName(BeanGenerator.OBJECT_FIELD_NAME),
            interfaceNameSyntax
        ));

        // 构建 (m_Object as IInterface).Event 访问表达式
        var memberAccess = SyntaxFactory.MemberAccessExpression(
            SyntaxKind.SimpleMemberAccessExpression,
            expressionSyntax,
            SyntaxFactory.IdentifierName(eventSymbol.Name)
        );

        // 构建事件声明
        var eventDeclaration = SyntaxFactory.EventDeclaration(
            SyntaxFactory.QualifiedName(interfaceNameSyntax, SyntaxFactory.IdentifierName(eventSymbol.Type.Name)),
            eventSymbol.Name
        ).WithExplicitInterfaceSpecifier(explicitInterfaceSpecifierSyntax);

        var ifDirectiveSyntax = SyntaxFactory.IfDirectiveTrivia(
            SyntaxFactory.IdentifierName("!DISABLE_DEBUGGER_ATTRIBUTE"),
            isActive: true,
            branchTaken: true,
            conditionValue: true
        );
        var endIfDirectiveSyntax = SyntaxFactory.EndIfDirectiveTrivia(isActive: true);

        // 添加 add 访问器
        var addAccessor = SyntaxFactory.AccessorDeclaration(SyntaxKind.AddAccessorDeclaration)
            .WithBody(SyntaxFactory.Block(
                BeanGenerator.GenerateAssertDisposeExpressionStatement(),
                SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.AssignmentExpression(
                        SyntaxKind.AddAssignmentExpression,
                        memberAccess,
                        SyntaxFactory.IdentifierName("value")
                    )
                )
            ))
            .AddAttributeLists([
                SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList([
                    SyntaxFactory.Attribute(SyntaxFactory.QualifiedName(
                        SyntaxFactory.IdentifierName($"global::{nameof(System)}.{nameof(System.Diagnostics)}"),
                        SyntaxFactory.IdentifierName(nameof(System.Diagnostics.DebuggerHiddenAttribute))
                    )),
                ])).WithLeadingTrivia(
                    SyntaxFactory.Trivia(ifDirectiveSyntax),
                    SyntaxFactory.CarriageReturnLineFeed
                ).WithTrailingTrivia(
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Trivia(endIfDirectiveSyntax)
                )
            ]);

        // 添加 remove 访问器
        var removeAccessor = SyntaxFactory.AccessorDeclaration(SyntaxKind.RemoveAccessorDeclaration)
            .WithBody(SyntaxFactory.Block(
                BeanGenerator.GenerateAssertDisposeExpressionStatement(),
                SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.AssignmentExpression(
                        SyntaxKind.SubtractAssignmentExpression,
                        memberAccess,
                        SyntaxFactory.IdentifierName("value")
                    )
                )
            ))
            .AddAttributeLists([
                SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList([
                    SyntaxFactory.Attribute(SyntaxFactory.QualifiedName(
                        SyntaxFactory.IdentifierName($"global::{nameof(System)}.{nameof(System.Diagnostics)}"),
                        SyntaxFactory.IdentifierName(nameof(System.Diagnostics.DebuggerHiddenAttribute))
                    )),
                ])).WithLeadingTrivia(
                    SyntaxFactory.Trivia(ifDirectiveSyntax),
                    SyntaxFactory.CarriageReturnLineFeed
                ).WithTrailingTrivia(
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Trivia(endIfDirectiveSyntax)
                )
            ]);

        // 添加访问器列表
        eventDeclaration = eventDeclaration.AddAccessorListAccessors(addAccessor, removeAccessor);

        return eventDeclaration;
    }

    //private static SimpleNameSyntax GetTypeArgumentTypeDefault(INamedTypeSymbol interfaceSymbol, IParameterSymbol parameterSymbol) {
    //    LogInfo($"{nameof(parameterSymbol)}={parameterSymbol}, {parameterSymbol.Type.GetType()}");
    //    return SyntaxFactory.IdentifierName(parameterSymbol.Type.Name);
    //}
    private static SimpleNameSyntax GetTypeArgumentTypeName(INamedTypeSymbol typeSymbol, string typeParameterName) {
        var index = -1;
        for (int i = 0; i < typeSymbol.TypeParameters.Length; i++) {
            ITypeParameterSymbol typeParameter = typeSymbol.TypeParameters[i];
            if (typeParameter.Name == typeParameterName) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            return SyntaxFactory.IdentifierName(typeParameterName);
        }
        var typeArgument = typeSymbol.TypeArguments[index];
        if (typeArgument is not INamedTypeSymbol typeArgumentNamedTypeSymbol) {
            return SyntaxFactory.IdentifierName(typeParameterName);
        }
        return typeArgumentNamedTypeSymbol.CreateSimpleNameSyntax();
    }

    /// <summary>
    /// 获取泛型类实现的所有接口（包括带泛型参数的接口，如 IData<T>）
    /// </summary>
    /// <param name="genericClassSymbol">泛型类符号（如 StructBox<T>）</param>
    /// <returns>接口符号列表，包含未构造的泛型接口及其类型参数</returns>
    private static IEnumerable<INamedTypeSymbol> GetImplementedInterfacesWithTypeParameters(INamedTypeSymbol genericClassSymbol) {
        if (genericClassSymbol == null || !genericClassSymbol.IsGenericType)
            yield break;

        // 遍历直接实现的接口（而非 AllInterfaces，避免递归）
        foreach (var implementedInterface in genericClassSymbol.Interfaces) {
            // 接口是泛型且未构造（如 IData<T>）
            if (implementedInterface.IsGenericType && !implementedInterface.IsUnboundGenericType) {
                // 解析接口的类型参数（可能包含类的泛型参数 T）
                var resolvedTypeArguments = implementedInterface.TypeArguments
                    .Select(arg => ResolveTypeArgument(arg, genericClassSymbol))
                    .ToArray();

                // 构造包含类型参数信息的接口符号
                var constructedInterface = implementedInterface.ConstructedFrom.Construct(resolvedTypeArguments);
                yield return constructedInterface;
            } else {
                // 非泛型接口或已构造的泛型接口（如 IData<int>）
                yield return implementedInterface;
            }
        }
    }

    /// <summary>
    /// 解析类型参数（将接口中的类型参数映射到类的泛型参数）
    /// </summary>
    private static ITypeSymbol ResolveTypeArgument(ITypeSymbol typeArgument, INamedTypeSymbol genericClassSymbol) {
        // 如果接口的类型参数是类的泛型参数（如 T），直接返回类的泛型参数符号
        if (typeArgument is ITypeParameterSymbol paramSymbol &&
            genericClassSymbol.TypeParameters.Contains(paramSymbol)) {
            return paramSymbol;
        }

        // 处理嵌套泛型（如 IData<IList<T>> 中的 IList<T>）
        if (typeArgument is INamedTypeSymbol namedType && namedType.IsGenericType) {
            var resolvedArgs = namedType.TypeArguments
                .Select(arg => ResolveTypeArgument(arg, genericClassSymbol))
                .ToArray();
            return namedType.ConstructedFrom.Construct(resolvedArgs);
        }

        return typeArgument;
    }

    private static TypeSyntax GetParameterType(ITypeSymbol typeSymbol, INamedTypeSymbol interfaceSymbol) {
        return typeSymbol switch {
            INamedTypeSymbol methodParamNamedTypeSymbol =>
                methodParamNamedTypeSymbol.CreateSimpleNameSyntax(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList<TypeSyntax>(
                    methodParamNamedTypeSymbol.TypeArguments.Select(
                        arg => arg is INamedTypeSymbol argNamedTypeSymbol
                            ? argNamedTypeSymbol.CreateSimpleNameSyntax()
                            : GetTypeArgumentTypeName(interfaceSymbol, arg.Name)
                    )
                ))),
            ITypeParameterSymbol methodParamTypeParameterSymbol =>
                GetTypeArgumentTypeName(interfaceSymbol, methodParamTypeParameterSymbol.Name),
            IArrayTypeSymbol methodParamArrayTypeSymbol => SyntaxFactory.ArrayType(
                GetParameterType(methodParamArrayTypeSymbol.ElementType, interfaceSymbol),
                SyntaxFactory.List([SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.SeparatedList<ExpressionSyntax>(
                    Enumerable.Repeat(
                        SyntaxFactory.OmittedArraySizeExpression(), // 生成省略号（表示未指定大小）
                        methodParamArrayTypeSymbol.Rank // 从IArrayTypeSymbol获取维度数量
                    )
                ))])
            ),
            _ => default,
        };
    }
}